package com.lakeworks.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.lakeworks.common.core.domain.AjaxResult;
import com.lakeworks.common.utils.SecurityUtils;
import com.lakeworks.common.utils.StringUtils;
import com.lakeworks.common.utils.http.HttpUtils;
import com.lakeworks.domain.ChannelInfo;
import com.lakeworks.domain.SysChannel;
import com.lakeworks.domain.SysChannelAuth;
import com.lakeworks.domain.SysProduct;
import com.lakeworks.mapper.SysChannelMapper;
import com.lakeworks.service.ISysChannelAuthService;
import com.lakeworks.service.ISysChannelService;
import com.lakeworks.service.ISysProductService;
import com.lakeworks.service.api.MerchantApiType;
import com.lakeworks.service.api.MerchantAsync;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.alibaba.fastjson.JSON.parseObject;

/**
 * 三方渠道信息Service业务层处理
 *
 * @author lake
 * @date 2023-02-08
 */
@Service
public class SysChannelServiceImpl implements ISysChannelService {
    @Autowired
    private SysChannelMapper sysChannelMapper;

    @Autowired
    private ISysChannelAuthService sysChannelAuthService;

    @Autowired
    private ISysProductService sysProductService;


    private static final ArrayList<String> urlList;

    static {
        urlList = new ArrayList<>();
        urlList.add("^https://([a-zA-Z0-9-]+)\\.inf-sea\\.net$");
        urlList.add("^https://([a-zA-Z0-9-]+)\\.dajingxiapp\\.com$");
        urlList.add("^https://([a-zA-Z0-9-]+)\\.dajingxiapp\\.cn$");
    }

    /**
     * 查询三方渠道信息
     *
     * @param id 三方渠道信息主键
     * @return 三方渠道信息
     */
    @Override
    @Cacheable(value = "sysChannelId", key = "#id",unless = "#result == null")
    public SysChannel selectSysChannelById(Long id) {
        return sysChannelMapper.selectSysChannelById(id);
    }

    /**
     * 查询三方渠道信息列表
     *
     * @param sysChannel 三方渠道信息
     * @return 三方渠道信息
     */
    @Override
    public List<SysChannel> selectSysChannelList(SysChannel sysChannel) {
        return sysChannelMapper.selectSysChannelList(sysChannel);
    }

    /**
     * 新增三方渠道信息
     *
     * @param sysChannel 三方渠道信息
     * @return 结果
     */
    @Override
    public int insertSysChannel(SysChannel sysChannel) {
        return sysChannelMapper.insertSysChannel(sysChannel);
    }

    /**
     * 修改三方渠道信息
     *
     * @param sysChannel 三方渠道信息
     * @return 结果
     */
    @Override
    public int updateSysChannel(SysChannel sysChannel) {
        return sysChannelMapper.updateSysChannel(sysChannel);
    }

    /**
     * 批量删除三方渠道信息
     *
     * @param ids 需要删除的三方渠道信息主键
     * @return 结果
     */
    @Override
    public int deleteSysChannelByIds(Long[] ids) {
        return sysChannelMapper.deleteSysChannelByIds(ids);
    }

    /**
     * 删除三方渠道信息信息
     *
     * @param id 三方渠道信息主键
     * @return 结果
     */
    @Override
    public int deleteSysChannelById(Long id) {
        return sysChannelMapper.deleteSysChannelById(id);
    }

    @Override
    public SysChannel selectSysChannelByCode(String code) {
        return sysChannelMapper.selectSysChannelByCode(code);
    }

    @Override
    public AjaxResult addChannel(ChannelInfo channelInfo) {
        AtomicReference<String> channelCode = new AtomicReference<String>();
        String userName = SecurityUtils.getUserName();
        urlList.forEach(s->{
            Pattern pattern = Pattern.compile(s);
            Matcher matcher = pattern.matcher(channelInfo.getChannelUrl());
            if (matcher.matches()) {
                channelCode.set(matcher.group(1));
            }
        });
        if(StringUtils.isBlank(channelCode.get())){
            return AjaxResult.error("渠道域名格式错误");
        }
        String code = checkUrl(channelInfo.getChannelUrl(), channelInfo.getAk(), channelInfo.getSk());
        if (code.equals("401")){
            return AjaxResult.error("AK,SK错误，签名验证未通过");
        }else if (code.equals("404")){
            return AjaxResult.error("渠道域名错误！");
        }else if (!code.equals("204")){
            return AjaxResult.error("服务器出现异常，请检查域名是否正确！");
        }
        //{"name": "桃洗", "color": "#EFCF28", "barcode": "10706", "baseurl": "https://peach.inf-sea.net"}
        if(channelCode.get().equals("waterfall")){
            channelCode.set("dajingxi");
        }
        SysChannel channel = sysChannelMapper.selectSysChannelByCode(channelCode.get());
        if (channel != null){
            return AjaxResult.error("渠道已存在");
        }
        String result = getPrefixAndProducts(channelInfo.getChannelUrl(), channelInfo.getAk(), channelInfo.getSk());
        String prefix = null;
        JSONObject jsonObject = null;
        if(StringUtils.isNotBlank(result)){
            jsonObject = parseObject(result);
            prefix = jsonObject.getString("prefix");
        }
        HashMap<String, String> map = new HashMap<>();
        map.put("name",channelInfo.getChannelName());
        map.put("color",channelInfo.getColor());
        if(StringUtils.isNotBlank(prefix)){
            map.put("barcode",prefix);
        }else {
            return AjaxResult.error("水洗码前缀为空");
        }
        map.put("baseurl",channelInfo.getChannelUrl());
        String jsonString = JSON.toJSONString(map);
        SysChannel build = SysChannel.builder()
                .code(channelCode.get())
                .config(jsonString)
                .name(channelInfo.getChannelName())
                .type(MerchantApiType.WATERFALL)
                .build();
        build.setCreateBy(userName);
        build.setModifyBy(userName);
        sysChannelMapper.insertSysChannel(build);
        sysChannelAuthService.insertSysChannelAuth(SysChannelAuth.builder()
                .channelId(build.getId())
                .ak(channelInfo.getAk())
                .sk(channelInfo.getSk())
                .authVersion("ROC-HmacSHA256-1.0")
                .createBy(userName)
                .modifyBy(userName)
                .build());
        JSONArray jsonArray = jsonObject.getJSONArray("productList");
        if(!jsonArray.isEmpty()){
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObj = jsonArray.getJSONObject(i);
                SysProduct sysProduct = SysProduct.builder()
                        .channelId(build.getId())
                        .code(jsonObj.getString("code"))
                        .name(jsonObj.getString("name"))
                        .category(jsonObj.getString("category"))
                        .picture(jsonObj.getString("picture"))
                        .build();
                sysProduct.setCreateBy(userName);
                sysProduct.setModifyBy(userName);
                sysProductService.insertSysProduct(sysProduct);
            }
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult updateChannel(ChannelInfo channelInfo) {
        SysChannel build = SysChannel.builder()
                .name(channelInfo.getChannelName())
                .color(channelInfo.getColor())
                .barcode(channelInfo.getBarcode())
                .build();
        build.setId(channelInfo.getId());
        updateSysChannel(build);
        return AjaxResult.success();
    }


    private String checkUrl(String url,String AK, String SK){
        String requestUrl = url + "/factory/factoryCheck";
        return HttpUtils.sendCheckRequest(AK, SK, requestUrl);
    }


    public String getPrefixAndProducts(String url,String AK, String SK){
        String requestUrl = url + "/factory/lake/factory";
        return HttpUtils.sendGetRequest(AK, SK, requestUrl);
    }

    public String selectConfigById(Long channelId) {
        return sysChannelMapper.selectConfigById(channelId);
    };


}
